package com.workManager.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.workManager.mapper.TbEstimateMapper;
import com.workManager.mapper.TdProfitMapper;
import com.workManager.pojo.TbEstimate;
import com.workManager.vo.ProfitVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by strangevy on 2017/6/26
 */
@Service
public class EstimateServiceImpl implements EstimateService {


    @Autowired
    private TbEstimateMapper estimateMapper;

    @Autowired
    private TdProfitMapper tdProfitMapper;

    public PageInfo<ProfitVo> queryProfit(Map map) {
        int pageno = !map.containsKey("pagenum") || map.get("pagenum") == null ? 1 : Integer.parseInt(map.get("pagenum").toString());
        int pagesize = !map.containsKey("pagesize") || map.get("pagesize") == null ? 10 : Integer.parseInt(map.get("pagesize").toString());
        PageHelper.startPage(pageno, pagesize);
        List<ProfitVo> profitList = tdProfitMapper.query(map);
        PageInfo<ProfitVo> profitPageInfo = new PageInfo<ProfitVo>(profitList);
        return profitPageInfo;
    }

    public Map queryNeedCost(List list) {
        Map map = new HashMap();
        List<Map<String, Object>> needList = estimateMapper.queryNeedCost(list);
        List<Map<String, Object>> directList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> procurementList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> costList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> indirectList = new ArrayList<Map<String, Object>>();
        double total = 0;
        Map<String, Double> yearTotal = new HashMap<String, Double>();

        for (Map<String, Object> n : needList) {
            if (yearTotal.containsKey(n.get("year"))) {
                yearTotal.put((String) n.get("year"), yearTotal.get(n.get("year")) + ((BigDecimal) n.get("amount")).doubleValue());
            } else {
                yearTotal.put((String) n.get("year"), ((BigDecimal) n.get("amount")).doubleValue());
            }
            total += ((BigDecimal) n.get("amount")).doubleValue();
            switch (n.get("type").toString()) {
                case "1":
                    costList.add(n);
                    break;
                case "2":
                    directList.add(n);
                    break;
                case "3":
                    procurementList.add(n);
                    break;
                case "4":
                    indirectList.add(n);
                    break;
            }
        }
        map.put("directList", directList);
        map.put("procurementList", procurementList);
        map.put("costList", costList);
        map.put("indirectList", indirectList);
        map.put("total", total);
        map.put("yearTotal", yearTotal);
        return map;
    }


    public Map queryActualCost(List list) throws ParseException {
        Map map = new HashMap();
        List<Map<String, Object>> actualList = estimateMapper.queryActualCost(list);
        List<Map<String, Object>> directList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> procurementList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> costList = new ArrayList<Map<String, Object>>();
        long minDate = 0L;
        long maxDate = 0L;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        for (Map<String, Object> actual : actualList) {
            if (minDate == 0 || sdf.parse((String) actual.get("minDate")).getTime() < minDate) {
                minDate = sdf.parse((String) actual.get("minDate")).getTime();
            }
            if (maxDate == 0 || sdf.parse((String) actual.get("maxDate")).getTime() > maxDate) {
                maxDate = sdf.parse((String) actual.get("maxDate")).getTime();
            }
            if (actual.get("type").toString().equals("1")) {
                directList.add(actual);
            } else if (actual.get("type").toString().equals("2")) {
                procurementList.add(actual);
            } else if (actual.get("type").toString().equals("3")) {
                costList.add(actual);
            }
        }


        map.put("directList", directList);
        map.put("procurementList", procurementList);
        map.put("costList", costList);
        map.put("indirectList", estimateMapper.queryIndirect(list));
        map.put("maxDate", sdf.format(maxDate));
        map.put("minDate", sdf.format(minDate));
        return map;
    }

    public Map queryTotalCost(List list){
        Map map = new HashMap();
        List<Map<String, Object>> totalList = estimateMapper.queryTotalCost(list);
        List<Map<String, Object>> directList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> procurementList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> costList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> indirectList = new ArrayList<Map<String, Object>>();
        double total = 0;
        Map<String, Double> yearTotal = new HashMap<String, Double>();

        for (Map<String, Object> t : totalList) {
            if (yearTotal.containsKey(t.get("year"))) {
                yearTotal.put((String) t.get("year"), yearTotal.get(t.get("year")) + ((BigDecimal) t.get("amount")).doubleValue());
            } else {
                yearTotal.put((String) t.get("year"), ((BigDecimal) t.get("amount")).doubleValue());
            }
            total += ((BigDecimal) t.get("amount")).doubleValue();
            switch (t.get("type").toString()) {
                case "1":
                    costList.add(t);
                    break;
                case "2":
                    directList.add(t);
                    break;
                case "3":
                    procurementList.add(t);
                    break;
                case "4":
                    indirectList.add(t);
                    break;
            }
        }
        map.put("directList", directList);
        map.put("procurementList", procurementList);
        map.put("costList", costList);
        map.put("indirectList", indirectList);
        map.put("total", total);
        map.put("yearTotal", yearTotal);
        return map;
    }

    private void addToYearTotal(Map<String, BigDecimal> yearTotal,List<Map<String,Object>> list){
        if (list != null && list.size() > 0) {
            for (Map<String,Object> m:list){
                String year = m.get("year").toString();

                if (yearTotal.get(year) == null) {
                    yearTotal.put(year,(BigDecimal)m.get("amount"));
                }else {
                    yearTotal.put(year,yearTotal.get(year).add((BigDecimal)m.get("amount")));
                }
            }
        }
    }

    public int save(TbEstimate estimate) {
        estimate.setCreateDate(new Date());
        return estimateMapper.insert(estimate);
    }

    public Map queryActualProfit(List list){
        Map map = new HashMap();
        List<Map<String,Object>> resultList = new ArrayList<>();
        Map<String,Double> yearTotal= new HashMap<>();

        List<String> yearList = estimateMapper.queryYearList(list);
        if (yearList != null && yearList.size() > 0) {
            for (String year : yearList){
                if (year == null || "".equals(year))
                    continue;

                List<Map<String,Object>> rList = estimateMapper.queryEstimateProfit(year,list);

                if (rList != null && rList.size()> 0) {
                    Map<String,Object> rMap = new HashMap<>();
                    rMap.put(year,rList.get(0));
                    resultList.add(rMap);

                    yearTotal.put(year,Double.valueOf(rList.get(0).get("actualIncome").toString()) - Double.valueOf(rList.get(0).get("actualCost").toString()));
                }
            }
        }

        map.put("yearTotal",yearTotal);
        map.put("yearList",resultList);

        return map;
    }

    public Map queryEstimateProfit(List list)throws ParseException{
        Map map = new HashMap();
        List<Map<String,Object>> resultList = new ArrayList<>();
        Map<String,Double> yearTotal= new HashMap<>();

        List<String> yearList = estimateMapper.queryYearList(list);
        if (yearList != null && yearList.size() > 0) {
            for (String year : yearList){
                if (year == null || "".equals(year))
                    continue;

                List<Map<String,Object>> rList = estimateMapper.queryEstimateProfit(year,list);

                if (rList != null && rList.size()> 0) {
                    Map<String,Object> rMap = new HashMap<>();
                    rMap.put(year,rList.get(0));
                    resultList.add(rMap);

                    yearTotal.put(year,(Double.valueOf(rList.get(0).get("estimateIncome").toString())+ Double.valueOf(rList.get(0).get("actualIncome").toString()))
                            - (Double.valueOf(rList.get(0).get("estimateCost").toString()) + Double.valueOf(rList.get(0).get("actualCost").toString())) );
                }
            }
        }

        map.put("yearTotal",yearTotal);
        map.put("yearList",resultList);

        return map;
    }
}
